package pe.com.cotelasa.seguridad.dominio.servicio.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.thoughtworks.xstream.XStream;

import pe.com.cotelasa.common.dao.excepcion.DAOException;
import pe.com.cotelasa.scp.dao.IDAOEmpresa;
import pe.com.cotelasa.scp.dao.IDAOUsuarioEmpresa;
import pe.com.cotelasa.scp.dominio.common.ESTADO_REGISTRO;
import pe.com.cotelasa.scp.dominio.common.util.UtilitarioCadenas;
import pe.com.cotelasa.scp.dominio.excepcion.ServiceException;
import pe.com.cotelasa.scp.entidad.Empresa;
import pe.com.cotelasa.seguridad.common.util.Constantes;
import pe.com.cotelasa.seguridad.controlador.backingBean.BKSession;
import pe.com.cotelasa.seguridad.dao.IDAORol;
import pe.com.cotelasa.seguridad.dao.IDAOUsuario;
import pe.com.cotelasa.seguridad.dominio.servicio.IServiceUsuario;
import pe.com.cotelasa.seguridad.entidad.Rol;
import pe.com.cotelasa.seguridad.entidad.Usuario;
import pe.com.cotelasa.seguridad.entidad.UsuarioEmpresa;
import pe.com.cotelasa.seguridad.entidad.UsuarioEmpresaPK;

@Service("servicioUsuario")
public class ServicioUsuarioImpl implements IServiceUsuario, Serializable {

    private static final long serialVersionUID = -4047409650599390161L;
    @Autowired
    private IDAOUsuario daoUsuario;
    @Autowired
    private IDAORol daoRol;
    @Autowired
    private IDAOEmpresa daoEmpresa;
    @Autowired
    private IDAOUsuarioEmpresa daoUsuarioEmpresa;
    @Autowired
    @Qualifier("passwordEncoder")
    private PasswordEncoder passwordEncoder;

    @Override
    public Usuario validarUsuarioPorCredencialesActivo(String usuario) throws ServiceException {
        Map<String, Object> parametros = new HashMap<String, Object>();
        parametros.put("usuario", usuario);
        parametros.put("estado_registro", new Character('A'));
        try {
            List<Usuario> listaUsuario = (List<Usuario>) daoUsuario.obtenerColeccionEntidadPorFiltros(Usuario.class, parametros);
            if (listaUsuario != null && !listaUsuario.isEmpty()) {
                return listaUsuario.get(0);
            } else {
                return null;
            }
        } catch (DAOException e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    @Override
    public void guardarUsuario(Usuario usuario, List<Empresa> listaBeanEmpresa, boolean esCodificarContrasena) throws ServiceException {
        
        usuario.setEstadoRegistro(Constantes.EstadoRegistro.ESTADO_REGISTRO_ACTIVO);
        if(esCodificarContrasena){
            usuario.setContracena(passwordEncoder.encodePassword(usuario.getContracena(), null));
        }
        if (usuario.getId() == null) {
            
            try {
                daoUsuario.insertar(usuario);
                usuario.setUsuarioEmpresaCollection(construirListaUsuarioEmpresa(listaBeanEmpresa, usuario, true));
                daoUsuario.actualizar(usuario);
            } catch (DAOException ex) {
                throw new ServiceException(ex);
            }
        } else {
            try {

                List<UsuarioEmpresa> listaUsuarioEmpresaEliminar = new ArrayList<UsuarioEmpresa>();
                List<UsuarioEmpresa> listaUsuarioEmpresaInsertar = new ArrayList<UsuarioEmpresa>();

                List<Empresa> listaEmpresaIniciales = daoEmpresa.obtenerListaEmpresasPorUsuario(usuario.getId());

                for (Empresa empresa00 : listaEmpresaIniciales) {
                    int cont = 0;
                    for (Empresa empresa01 : listaBeanEmpresa) {
                        if (empresa00.getId().equals(empresa01.getId())) {
                            cont++;
                        }
                    }
                    if (cont == 0) {
                        listaUsuarioEmpresaEliminar.add(daoUsuarioEmpresa.obtenerUsuarioEmpresa(new UsuarioEmpresaPK(empresa00.getId(), usuario.getId())));
                    }
                }



                for (Empresa empresa02 : listaBeanEmpresa) {
                    int cont = 0;
                    for (Empresa empresa03 : listaEmpresaIniciales) {
                        if (empresa02.getId().equals(empresa03.getId())) {
                            cont++;
                        }
                    }
                    if (cont == 0) {
                        listaUsuarioEmpresaInsertar.add(new UsuarioEmpresa(new UsuarioEmpresaPK(empresa02.getId(), usuario.getId()), Constantes.EstadoRegistro.ESTADO_REGISTRO_ACTIVO, "jporras", new Date()));
                    }

                }

                daoUsuarioEmpresa.eliminarColeccion(listaUsuarioEmpresaEliminar);
                daoUsuarioEmpresa.insertarColeccion(listaUsuarioEmpresaInsertar);
                usuario.setUsuarioEmpresaCollection(null);
                System.out.println("contraseña actualizar 2: "+usuario.getContracena());
                System.out.println("tipo de rol 3 : "+usuario.getIdRol().getId());
                usuario.setIdRol(daoRol.obtenerEntidadPorId(Rol.class, usuario.getIdRol().getId()));
                System.out.println("rol: "+usuario.getIdRol().getNombre());
                daoUsuario.actualizar(usuario);
                System.out.println("tipo de rol 4 : "+usuario.getIdRol().getId());
            } catch (DAOException ex) {
                throw new ServiceException(ex);
            }
        }
    }

    private List<UsuarioEmpresa> construirListaUsuarioEmpresa(List<Empresa> listaEmpresa, Usuario beanUsuario, boolean flagGuardar) {
        List<UsuarioEmpresa> listaUsuarioEmpresa = null;
        UsuarioEmpresa usuarioEmpresa = null;
        if (listaEmpresa != null) {
            listaUsuarioEmpresa = new ArrayList<UsuarioEmpresa>();
            for (Empresa empresa : listaEmpresa) {
                usuarioEmpresa = new UsuarioEmpresa();
                usuarioEmpresa.setUsuarioEmpresaPK(new UsuarioEmpresaPK(empresa.getId(), beanUsuario.getId()));
                usuarioEmpresa.setEstadoRegistro(Constantes.EstadoRegistro.ESTADO_REGISTRO_ACTIVO);
                listaUsuarioEmpresa.add(usuarioEmpresa);
                if (flagGuardar) {
//					usuarioEmpresa.setUsrCreacion(bkSession.getUsuario().getUsuario());
                    usuarioEmpresa.setUsrCreacion(beanUsuario.getUsrCreacion());
                    usuarioEmpresa.setFecCreacion(new Date());
                } else {
                    usuarioEmpresa.setFecModificacion(new Date());
//					usuarioEmpresa.setUsrModificacion(bkSession.getUsuario().getUsuario());
                    usuarioEmpresa.setUsrModificacion(beanUsuario.getUsrCreacion());
                }
            }
        }
        return listaUsuarioEmpresa;
    }

    @Override
    public List<Usuario> obtenerListaUsuarios(Usuario usuario) throws ServiceException {
        Map<String, Object> parametros = new HashMap<String, Object>();
        parametros.put("usuario", usuario.getUsuario());
        parametros.put("nombres", usuario.getNombres());
        parametros.put("apellidos", usuario.getApellidos());
        parametros.put("estado_registro", ESTADO_REGISTRO.ACTIVO.getValor());
        try {
            Collection<Usuario> coleccionUsuario = daoUsuario.obtenerColeccionEntidadPorFiltros(Usuario.class, parametros);
            return (List<Usuario>) coleccionUsuario;
        } catch (DAOException ex) {
            throw new ServiceException(ex.getMessage(), ex);
        }
    }

    @Override
    public Usuario obtenerUsuarioPorId(Integer idUsuario) throws ServiceException {
        try {
            return daoUsuario.obtenerEntidadPorId(Usuario.class, idUsuario);
        } catch (DAOException ex) {
            throw new ServiceException(ex.getMessage(), ex);
        }
    }

    @Override
    public void eliminacionLogica(Usuario usuario) throws ServiceException {
        try {
            Map<String, Object> parametros = new HashMap<String, Object>();
            parametros.put("usuarioEmpresaPK.idUsuario", usuario.getId());
            usuario.setEstadoRegistro(Constantes.EstadoRegistro.ESTADO_REGISTRO_ELIMINADO);
            daoUsuario.actualizar(usuario);
            List<UsuarioEmpresa> listaUsuarioEmpresa = (List<UsuarioEmpresa>) daoUsuarioEmpresa.obtenerColeccionEntidadPorFiltros(UsuarioEmpresa.class, parametros);
            List<UsuarioEmpresa> listaUsuarioEmpresaActualizar = new ArrayList<UsuarioEmpresa>();
            for (UsuarioEmpresa usuarioEmpresa : listaUsuarioEmpresa) {
                usuarioEmpresa.setEstadoRegistro(Constantes.EstadoRegistro.ESTADO_REGISTRO_ELIMINADO);
                listaUsuarioEmpresaActualizar.add(usuarioEmpresa);
            }
            daoUsuarioEmpresa.actualizarColeccion(listaUsuarioEmpresaActualizar);
        } catch (DAOException ex) {
            throw new ServiceException(ex.getMessage(), ex);
        }
    }

    @Override
    public void actualizarUsuario(Usuario beanUsuario) throws ServiceException {
        try {
            daoUsuario.actualizar(beanUsuario);
        } catch (DAOException e) {
            throw new ServiceException(e);
        }
    }
}
